package com.info33.platform.common.mvc.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.info33.platform.common.constant.TableConstant;
import com.info33.platform.common.mvc.entity.BaseEntity;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.common.validated.SaveValidated;
import com.info33.platform.common.validated.UpdateValidated;
import com.info33.platform.common.validated.ValidList;
import com.info33.platform.system.vo.SysUserVO;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 基础 Controller
 *
 * @param <M> Service
 * @param <T> Entity
 * @author Administrator
 */
public class BaseController<M extends IService<T>, T extends BaseEntity> {

    private final M baseService;

    public BaseController(M baseService) {
        this.baseService = baseService;
    }

    /**
     * 获取当前主体
     *
     * @return -
     */
    public Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    /**
     * 获取当前用户
     *
     * @return -
     */
    public SysUserVO getCurrentUser() {
        Subject subject = getSubject();
        return (SysUserVO) subject.getPrincipal();
    }

    /**
     * 获取当前用户租户用户 id
     *
     * @return -
     */
    public Long getTenantUserId() {
        SysUserVO currentUser = getCurrentUser();
        if (!ObjectUtils.isEmpty(currentUser.getSysTenantUserVO())) {
            return currentUser.getSysTenantUserVO().getId();
        }
        return currentUser.getAppTenantUserVO().getId();
    }

    /**
     * 获取当前用户租户 id
     *
     * @return -W
     */
    public Long getTenantId() {
        return getCurrentUser().getTenant().getId();
    }

    @GetMapping(value = "/base/{id}")
    @ApiOperation(value = "base - 详情", hidden = true)
    public Result<T> baseGet(
            @PathVariable(value = "id") Long id) {
        return Result.ok(baseService.getById(id));
    }

    @PostMapping(value = "/base/list")
    @ApiOperation(value = "base - 集合", notes = "可选入参完全匹配查询，同时匹配已经登录用户的租户过虑", hidden = true)
    public Result<List<T>> baseGetList(
            @RequestBody T t) {
        return Result.ok(baseService.list(new QueryWrapper<>(t)
                .eq(TableConstant.TENANT_ID, getTenantId())
                .orderByAsc(TableConstant.SORT)
                .orderByDesc(TableConstant.CREATE_DATE)
                .orderByAsc(TableConstant.ID)));
    }

    @PostMapping(value = "/base/list/{pageNum}/{pageSize}")
    @ApiOperation(value = "base - 分页", notes = "可选入参完全匹配查询，同时匹配已经登录用户的租户过虑", hidden = true)
    public Result<IPage<T>> baseGetList(
            @RequestBody T t,
            @PathVariable int pageNum,
            @PathVariable int pageSize) {
        return Result.ok(baseService.page(new Page<>(pageNum, pageSize), new QueryWrapper<>(t)
                .eq(TableConstant.TENANT_ID, getTenantId())
                .orderByAsc(TableConstant.SORT)
                .orderByDesc(TableConstant.CREATE_DATE)
                .orderByAsc(TableConstant.ID)));
    }

    @PostMapping("/base/add")
    @ApiOperation(value = "base - 增加")
    public Result<T> baseAdd(
            @Validated(value = {SaveValidated.class}) @RequestBody T t) {
        return baseService.save(t) ? Result.ok(t) : Result.error();
    }

    @PostMapping("/base/addBatch")
    @ApiOperation(value = "base - 批增加", hidden = true)
    public Result<List<T>> baseAddBatch(
            @Validated(value = {SaveValidated.class}) @RequestBody ValidList<T> t) {
        return baseService.saveBatch(t) ? Result.ok(t) : Result.error();
    }

    @PutMapping("/base/edit")
    @ApiOperation(value = "base - 修改", hidden = true)
    public Result<T> baseEdit(
            @Validated(value = {UpdateValidated.class}) @RequestBody T t) {
        return baseService.updateById(t) ? Result.ok(baseService.getById(t.getId())) : Result.error();
    }

    @PutMapping("/base/editBatch")
    @ApiOperation(value = "base - 批修改", hidden = true)
    public Result<List<T>> baseEditBatch(
            @Validated(value = {UpdateValidated.class}) @RequestBody ValidList<T> t) {
        return baseService.updateBatchById(t) ? Result.ok(t) : Result.error();
    }

    @DeleteMapping("/base/remove/{id}")
    @ApiOperation(value = "base - 删除", notes = "根据 id 删除库数据")
    public Result<Object> baseRemove(
            @PathVariable(value = "id") Long id) {
        return baseService.removeById(id) ? Result.ok() : Result.error();
    }

}
